#include "EventLoop.hpp"
#include "TcpConnect.hpp"
#include "InetAddress.hpp"
#include <netinet/in.h>
#include <sys/socket.h>

namespace wd{


TcpConnection::TcpConnection(int clientfd,EventLoop * eventloop)
:_sock(clientfd)
,_sockio(clientfd)
,_localAddr(getLocalAddr())
,_peerAddr(getPeerAddr())
,_peventloop(eventloop)
{
}

string TcpConnection::receive(){
    char buf[65535] = {0};
    int ret = _sockio.readline(buf,sizeof(buf));
    return string(buf,ret);
}

void TcpConnection::send(const string& msg){
    _sockio.sendn(msg.c_str(),msg.size());
}

struct sockaddr_in TcpConnection::getLocalAddr(){
    struct sockaddr_in addr;
    memset(&addr,0,sizeof(addr));
    socklen_t len = sizeof(addr);
    int ret = getsockname(_sock.fd(),(struct sockaddr*)&addr,&len);
    if(ret < 0){
        perror("getsockname");
    }
    return addr;
}
    
struct sockaddr_in TcpConnection::getPeerAddr(){
    struct sockaddr_in addr;
    memset(&addr,0,sizeof(addr));
    socklen_t len = sizeof(addr);
    int ret = getpeername(_sock.fd(),(struct sockaddr*)&addr,&len);
    if(ret < 0){
        perror("getpeername");
    }
    return addr;

}

bool TcpConnection::isclose() const{
    char buff[1000] = {0};
    int ret = _sockio.recvPeek(buff,1000);
    return ret == 0;
}

void TcpConnection::setAllCallbacks(const Callback & onConnection,
                         const Callback & onMessage,
                         const Callback & onClose){

    _onConnection = onConnection;
    _onMessage = onMessage;
    _onClose = onClose;
}
//将send函数转为函数对象给EventLoop
void TcpConnection::sendInLoop(const string & msg){
    if(_peventloop){
        _peventloop->runInLoop(std::bind(&TcpConnection::send, this,msg));
    }
}

}
